home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / circuits / spice2g6.z / spice2g6 / spice / Fortran / diode.f < prev    next >
Encoding:
Text File  |  1989-02-03  |  5.9 KB  |  207 lines

  1.       subroutine diode
  2.       implicit double precision (a-h,o-z)
  3. c
  4. c     this routine processes diodes for dc and transient analyses.
  5. c
  6. c spice version 2g.6  sccsid=tabinf 3/15/83
  7.       common /tabinf/ ielmnt,isbckt,nsbckt,iunsat,nunsat,itemps,numtem,
  8.      1   isens,nsens,ifour,nfour,ifield,icode,idelim,icolum,insize,
  9.      2   junode,lsbkpt,numbkp,iorder,jmnode,iur,iuc,ilc,ilr,numoff,isr,
  10.      3   nmoffc,iseq,iseq1,neqn,nodevs,ndiag,iswap,iequa,macins,lvnim1,
  11.      4   lx0,lvn,lynl,lyu,lyl,lx1,lx2,lx3,lx4,lx5,lx6,lx7,ld0,ld1,ltd,
  12.      5   imynl,imvn,lcvn,nsnod,nsmat,nsval,icnod,icmat,icval,
  13.      6   loutpt,lpol,lzer,irswpf,irswpr,icswpf,icswpr,irpt,jcpt,
  14.      7   irowno,jcolno,nttbr,nttar,lvntmp
  15. c spice version 2g.6  sccsid=cirdat 3/15/83
  16.       common /cirdat/ locate(50),jelcnt(50),nunods,ncnods,numnod,nstop,
  17.      1   nut,nlt,nxtrm,ndist,ntlin,ibr,numvs,numalt,numcyc
  18. c spice version 2g.6  sccsid=status 3/15/83
  19.       common /status/ omega,time,delta,delold(7),ag(7),vt,xni,egfet,
  20.      1   xmu,sfactr,mode,modedc,icalc,initf,method,iord,maxord,noncon,
  21.      2   iterno,itemno,nosolv,modac,ipiv,ivmflg,ipostp,iscrch,iofile
  22. c spice version 2g.6  sccsid=knstnt 3/15/83
  23.       common /knstnt/ twopi,xlog2,xlog10,root2,rad,boltz,charge,ctok,
  24.      1   gmin,reltol,abstol,vntol,trtol,chgtol,eps0,epssil,epsox,
  25.      2   pivtol,pivrel
  26. c spice version 2g.6  sccsid=blank 3/15/83
  27.       common /blank/ value(200000)
  28.       integer nodplc(64)
  29.       complex cvalue(32)
  30.       equivalence (value(1),nodplc(1),cvalue(1))
  31. c
  32. c
  33.       dimension vdo(1),cdo(1),gdo(1),qd(1),cqd(1)
  34.       equivalence (vdo(1),value(1)),(cdo(1),value(2)),
  35.      1   (gdo(1),value(3)),(qd(1),value(4)),(cqd(1),value(5))
  36. c
  37. c
  38.       loc=locate(11)
  39.    10 if ((loc.eq.0).or.(nodplc(loc+16).ne.0)) return
  40.       locv=nodplc(loc+1)
  41.       node1=nodplc(loc+2)
  42.       node2=nodplc(loc+3)
  43.       node3=nodplc(loc+4)
  44.       locm=nodplc(loc+5)
  45.       ioff=nodplc(loc+6)
  46.       locm=nodplc(locm+1)
  47.       loct=nodplc(loc+11)
  48. c
  49. c  dc model parameters
  50. c
  51.       area=value(locv+1)
  52.       csat=value(locm+1)*area
  53.       gspr=value(locm+2)*area
  54.       vte=value(locm+3)*vt
  55.       bv=value(locm+13)
  56.       vcrit=value(locm+18)
  57. c
  58. c  initialization
  59. c
  60.       icheck=1
  61.       go to (100,20,30,50,60,70),initf
  62.    20 if(mode.ne.1.or.modedc.ne.2.or.nosolv.eq.0) go to 25
  63.       vd=value(locv+2)
  64.       go to 300
  65.    25 if(ioff.ne.0) go to 40
  66.       vd=vcrit
  67.       go to 300
  68.    30 if (ioff.eq.0) go to 100
  69.    40 vd=0.0d0
  70.       go to 300
  71.    50 vd=vdo(lx0+loct)
  72.       go to 300
  73.    60 vd=vdo(lx1+loct)
  74.       go to 300
  75.    70 xfact=delta/delold(2)
  76.       vdo(lx0+loct)=vdo(lx1+loct)
  77.       vd=(1.0d0+xfact)*vdo(lx1+loct)-xfact*vdo(lx2+loct)
  78.       cdo(lx0+loct)=cdo(lx1+loct)
  79.       gdo(lx0+loct)=gdo(lx1+loct)
  80.       go to 110
  81. c
  82. c  compute new nonlinear branch voltage
  83. c
  84.   100 vd=value(lvnim1+node3)-value(lvnim1+node2)
  85.   110 delvd=vd-vdo(lx0+loct)
  86.       cdhat=cdo(lx0+loct)+gdo(lx0+loct)*delvd
  87. c
  88. c  bypass if solution has not changed
  89. c
  90.       if (initf.eq.6) go to 200
  91.       tol=reltol*dmax1(dabs(vd),dabs(vdo(lx0+loct)))+vntol
  92.       if (dabs(delvd).ge.tol) go to 200
  93.       tol=reltol*dmax1(dabs(cdhat),dabs(cdo(lx0+loct)))+abstol
  94.       if (dabs(cdhat-cdo(lx0+loct)).ge.tol) go to 200
  95.       vd=vdo(lx0+loct)
  96.       cd=cdo(lx0+loct)
  97.       gd=gdo(lx0+loct)
  98.       go to 800
  99. c
  100. c  limit new junction voltage
  101. c
  102.   200 vlim=vte+vte
  103.       if(bv.eq.0.0d0) go to 205
  104.       if (vd.lt.dmin1(0.0d0,-bv+10.0d0*vte)) go to 210
  105.   205 call pnjlim(vd,vdo(lx0+loct),vte,vcrit,icheck)
  106.       go to 300
  107.   210 vdtemp=-(vd+bv)
  108.       call pnjlim(vdtemp,-(vdo(lx0+loct)+bv),vte,vcrit,icheck)
  109.       vd=-(vdtemp+bv)
  110. c
  111. c  compute dc current and derivitives
  112. c
  113.   300 if (vd.lt.-5.0d0*vte) go to 310
  114.       evd=dexp(vd/vte)
  115.       cd=csat*(evd-1.0d0)+gmin*vd
  116.       gd=csat*evd/vte+gmin
  117.       go to 330
  118.   310 if(bv.eq.0.0d0) go to 315
  119.       if(vd.lt.-bv) go to 320
  120.   315 gd=-csat/vd+gmin
  121.       cd=gd*vd
  122.       go to 330
  123.   320 evrev=dexp(-(bv+vd)/vt)
  124.       cd=-csat*(evrev-1.0d0+bv/vt)
  125.       gd=csat*evrev/vt
  126.   330 if (mode.ne.1) go to 500
  127.       if ((modedc.eq.2).and.(nosolv.ne.0)) go to 500
  128.       if (initf.eq.4) go to 500
  129.       go to 700
  130. c
  131. c  charge storage elements
  132. c
  133.   500 tau=value(locm+4)
  134.       czero=value(locm+5)*area
  135.       pb=value(locm+6)
  136.       xm=value(locm+7)
  137.       fcpb=value(locm+12)
  138.       if (vd.ge.fcpb) go to 510
  139.       arg=1.0d0-vd/pb
  140.       sarg=dexp(-xm*dlog(arg))
  141.       qd(lx0+loct)=tau*cd+pb*czero*(1.0d0-arg*sarg)/(1.0d0-xm)
  142.       capd=tau*gd+czero*sarg
  143.       go to 520
  144.   510 f1=value(locm+15)
  145.       f2=value(locm+16)
  146.       f3=value(locm+17)
  147.       czof2=czero/f2
  148.       qd(lx0+loct)=tau*cd+czero*f1+czof2*(f3*(vd-fcpb)
  149.      1   +(xm/(pb+pb))*(vd*vd-fcpb*fcpb))
  150.       capd=tau*gd+czof2*(f3+xm*vd/pb)
  151. c
  152. c  store small-signal parameters
  153. c
  154.   520 if ((mode.eq.1).and.(modedc.eq.2).and.(nosolv.ne.0)) go to 700
  155.       if (initf.ne.4) go to 600
  156.       value(lx0+loct+4)=capd
  157.       go to 1000
  158. c
  159. c  transient analysis
  160. c
  161.   600 if (initf.ne.5) go to 610
  162.       qd(lx1+loct)=qd(lx0+loct)
  163.   610 call intgr8(geq,ceq,capd,loct+3)
  164.       gd=gd+geq
  165.       cd=cd+cqd(lx0+loct)
  166.       if (initf.ne.5) go to 700
  167.       cqd(lx1+loct)=cqd(lx0+loct)
  168. c
  169. c  check convergence
  170. c
  171.   700 if (initf.ne.3) go to 710
  172.       if (ioff.eq.0) go to 710
  173.       go to 750
  174.   710 if (icheck.eq.1) go to 720
  175.       tol=reltol*dmax1(dabs(cdhat),dabs(cd))+abstol
  176.       if (dabs(cdhat-cd).le.tol) go to 750
  177.   720 noncon=noncon+1
  178.   750 vdo(lx0+loct)=vd
  179.       cdo(lx0+loct)=cd
  180.       gdo(lx0+loct)=gd
  181. c
  182. c  load current vector
  183. c
  184.   800 cdeq=cd-gd*vd
  185.       value(lvn+node2)=value(lvn+node2)+cdeq
  186.       value(lvn+node3)=value(lvn+node3)-cdeq
  187. c
  188. c  load matrix
  189. c
  190.       locy=lvn+nodplc(loc+13)
  191.       value(locy)=value(locy)+gspr
  192.       locy=lvn+nodplc(loc+14)
  193.       value(locy)=value(locy)+gd
  194.       locy=lvn+nodplc(loc+15)
  195.       value(locy)=value(locy)+gd+gspr
  196.       locy=lvn+nodplc(loc+7)
  197.       value(locy)=value(locy)-gspr
  198.       locy=lvn+nodplc(loc+8)
  199.       value(locy)=value(locy)-gd
  200.       locy=lvn+nodplc(loc+9)
  201.       value(locy)=value(locy)-gspr
  202.       locy=lvn+nodplc(loc+10)
  203.       value(locy)=value(locy)-gd
  204.  1000 loc=nodplc(loc)
  205.       go to 10
  206.       end
  207.